home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / util / cli / BinHex.lha / Source / BinHex.c next >
C/C++ Source or Header  |  1996-11-21  |  9KB  |  336 lines

  1. #define NAME     "BinHex"
  2. #define REVISION "12"
  3. #define ENDCODE
  4. //#define DEBUG
  5.  
  6. /* Programmheader
  7.  
  8.     Name:        BinHex
  9.     Author:        SDI
  10.     Distribution:    PD
  11.     Description:    wandelt Binär in Hex Datei und umgekehrt
  12.     Compileropts:    -
  13.     Linkeropts:    -
  14.  
  15.  1.0   03.10.95 : erste Version
  16.  1.1   15.10.95 : neu übersetzt
  17.  1.2   05.02.96 : mit verbesserten Includes neu übersetzt
  18.  1.3   06.02.96 : MakeHEX statt MakeBASE
  19.  1.4   10.02.96 : mit eigenem StartUp übersetzt
  20.  1.5   12.03.96 : Fehler mit ONLYDATA behoben, \ Option, Englische Texte
  21.  1.6   04.05.96 : Fehler mit ReadArgs behoben
  22.  1.7   11.05.96 : Option ROWS eingebaut
  23.  1.8   12.05.96 : Option ASMDATA eingebaut
  24.  1.9   11.06.96 : EndCode nach SDI_defines.h
  25.  1.10  16.06.96 : Bug overworked Buffer - corrected
  26.  1.11  06.10.96 : if last char was an \t program hanged - fixed
  27.  1.12  21.11.96 : added option CDATA, same as ASMDATA but for C
  28. */
  29.  
  30. #include <pragma/dos_lib.h>
  31. #include <pragma/exec_lib.h>
  32. #include <dos/dos.h>
  33. #include <exec/memory.h>
  34. #include "SDI_defines.h"
  35. #include "SDI_structures.h"
  36. #include "SDI_ASM_STD_protos.h"
  37. #include "SDI_ASM_protos.h"
  38. #include "SDI_protos.h"
  39. #include "GetLength.c"  // These files are in SDI_functions.o
  40. #include "Eingabe.c"    // remove the lines and build your own
  41. #include "Ausgabe.c"    // makefile
  42. #include "Free.c"       // Add also the other .o files to the
  43. #include "GetPuffer.c"  // makefile to make compilation
  44. #include "PutNum.c"     // succesfull!
  45.  
  46. struct SDI_InOut    bin        = {0, 0, 0, 0, 0},
  47.             hex        = {0, 0, 0, 0, 0};
  48. struct RDArgs        *rda        = 0;
  49. ULONG            DosVersion    = 37;    // zwingt OS 37 !
  50.  
  51. #define line        h
  52. #define row        adress
  53.  
  54. #define PARAM "BIN/A,HEX/A,MAKEBIN/S,ONLYDATA/S,ROWS/N,ASMDATA/S,CDATA/S"
  55.  
  56. #define NUMPERLINE    (rows<<2)
  57. #define LINESIZE    (rows*(4*(2+1)+1)+8+1+1)
  58. // Reihenanzahl*(4*(2Zahlen+1Asciizeichen)+1Leerzeichen)+8für Adresse+
  59. // 1Leerzeichen+1Return
  60. #define MAINSIZE    (rows*(4*2+1))
  61. #define ASCIIPOS    (MAINSIZE+8+1)
  62. #define RESTSIZE    (NUMPERLINE+8+1+1)
  63.  
  64. UBYTE GetHEXNum(UBYTE);
  65.  
  66. void main(void)
  67. {
  68.   struct {
  69.     STRPTR    bin;
  70.     STRPTR    hex;
  71.     LONG    makebin;
  72.     LONG    onlydata;
  73.     LONG    *rows;
  74.     LONG    asmdata;
  75.     LONG    cdata;
  76.     } args = {0, 0, 0, 0, 0, 0, 0};
  77.   UBYTE realmode = 0;
  78.   ULONG h, adress = 0;
  79.   STRPTR strptr;
  80.   UBYTE rows = 5;
  81.  
  82.   if(!(rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
  83.     End(RETURN_FAIL);
  84.  
  85.   rda->RDA_ExtHelp =
  86. /*
  87.   "Mit dem Programm können binäre Dateien in Hexadezimal dargestellte "
  88.   "Dateien umgewandelt werden. Diese kann man dann mit einem Editor "
  89.   "bearbeitet und wieder in eine Binärdatei umwandeln. "
  90.   "Das Programm liest aus der Hexdatei alle Hex-Zahlen bis zu einem "
  91.   "Tabulator, dann geht es nach dem nächsten Return weiter. Sie müssen "
  92.   "also nicht darauf achten, wieder die genaue Zeilenlänge zu erhalten. "
  93.   "Zwischen Return und Tabulator dürfen jedoch nur die Zeichen 0-9 und A-F "
  94.   "stehen und zwar in einer geraden Anzahl. Das Leerzeichen ist als "
  95.   "Trenner erlaubt. Nach einem \\ wird alles so übernommen, wie gegeben. "
  96.   "Das ist für Texteingaben sehr nützlich.\n";
  97. */
  98.   "Use this program to convert binary data into hexadecimal data. This "
  99.   "could be edited with a normal text editor. After that it could again "
  100.   "be made to binary. The program reads in the hexadecimal file all numbers "
  101.   "from line start to next tabulator or return. You don't need to make the "
  102.   "linelength exact as before! Only 0-9 and A-F are allowed in the data part. "
  103.   "Spaces and data after the tabulator are ignored. After a \\ all data is "
  104.   "not converted and taken as given to the binary file (useful for texts).\n";
  105.   if(!ReadArgs(PARAM, (LONG *) &args, rda))
  106.     End(RETURN_FAIL);
  107.  
  108.   if(args.rows && *args.rows > 0 && *args.rows < 256)
  109.     rows = (UBYTE) *args.rows;
  110.  
  111.   if(args.asmdata || args.cdata)
  112.     args.onlydata = 1;
  113.  
  114.   if((args.makebin && (args.asmdata || args.cdata)) ||
  115.   (args.asmdata && args.cdata))
  116.   {
  117.     PrintFault(ERROR_TOO_MANY_ARGS, 0);
  118.     End(RETURN_FAIL);
  119.   }
  120.  
  121.   if(args.makebin)
  122.   {
  123.     if(
  124.     !(hex.file = Open(args.hex, MODE_OLDFILE)) ||
  125.     !(bin.size = GetLength(args.hex)))
  126.       End(RETURN_FAIL);
  127.     bin.size = (bin.size >> 2) + 1;
  128.     if(bin.size < NUMPERLINE)
  129.       bin.size = NUMPERLINE;
  130.   }
  131.   else
  132.   {
  133.     if(
  134.     !(bin.file = Open(args.bin, MODE_OLDFILE)) ||
  135.     !(bin.size = GetLength(args.bin)))
  136.       End(RETURN_FAIL);
  137.   }
  138.  
  139.   if((hex.size = bin.size << 2) > (h = AvailMem(MEMF_LARGEST)))
  140.     hex.size = h;
  141.   if(hex.size < LINESIZE)
  142.     hex.size = LINESIZE;
  143.   if(!GetPuffer(&hex))
  144.     End(RETURN_FAIL);
  145.  
  146.   if(bin.size > (h = AvailMem(MEMF_LARGEST)))
  147.     bin.size = h;
  148.   if(!GetPuffer(&bin))
  149.     End(RETURN_FAIL);
  150.  
  151.   if(!((args.makebin ? bin.file : hex.file) = 
  152.   Open(args.makebin ? args.bin : args.hex, MODE_NEWFILE)))
  153.     End(RETURN_FAIL);
  154.  
  155. #ifdef DEBUG
  156.   PutNum((ULONG)bin.file, 10); PutStr(" bin.file\n");
  157.   PutNum((ULONG)bin.buf , 10); PutStr(" bin.buf\n");
  158.   PutNum((ULONG)bin.pos , 10); PutStr(" bin.pos\n");
  159.   PutNum((ULONG)bin.size, 10); PutStr(" bin.size\n");
  160.   PutNum((ULONG)hex.file, 10); PutStr(" hex.file\n");
  161.   PutNum((ULONG)hex.buf , 10); PutStr(" hex.buf\n");
  162.   PutNum((ULONG)hex.pos , 10); PutStr(" hex.pos\n");
  163.   PutNum((ULONG)hex.size, 10); PutStr(" hex.size\n");
  164. #endif
  165.  
  166.   if(args.makebin)
  167.   {
  168.     Eingabe(&hex); line = row = 1;
  169.     while(hex.count && !CTRL_C)
  170.     {
  171.       if(*hex.pos == '\t')
  172.       {
  173.         while(hex.count && *hex.pos != '\n')
  174.         {
  175.           ++hex.pos;
  176.           if(hex.pos >= hex.buf + hex.count - 2)
  177.             Eingabe(&hex);
  178.         }
  179.       }
  180.       else if(*hex.pos == '\n')
  181.       {
  182.         ++line; row = 1; ++hex.pos; realmode = 0;
  183.       }
  184.       else if(!realmode && *hex.pos == ' ')
  185.       {
  186.         ++hex.pos; ++row;
  187.       }
  188.       else if(*hex.pos == '\\')
  189.       {
  190.         realmode = 1; ++hex.pos;
  191.       }
  192.       else
  193.       {
  194.         if(realmode)
  195.         {
  196.           *(bin.pos++) = *(hex.pos++); ++row;
  197.         }
  198.         else
  199.         {
  200.           if(!SDI_isxdigit(*hex.pos) || !SDI_isxdigit(*(hex.pos+1)))
  201.           {
  202. /*
  203.         PutStr("Zeile "); PutNum(line, 0);
  204.             PutStr(", Reihe "); PutNum(row, 0); PutStr(" : ");
  205. */
  206.             PutStr("line "); PutNum(line, 0);
  207.         PutStr(", row "); PutNum(row, 0); PutStr(" : ");
  208.         SetIoErr(ERROR_SEEK_ERROR);
  209.             End(RETURN_FAIL);
  210.           }
  211.           *bin.pos = GetHEXNum(*(hex.pos++)) << 4;
  212.           *(bin.pos++) += GetHEXNum(*(hex.pos++));
  213.           row+=2;
  214.         }
  215.       }
  216.       if(hex.pos >= hex.buf + hex.count - 2)
  217.         Eingabe(&hex);
  218.       if(bin.pos >= bin.buf + bin.size)
  219.         Ausgabe(&bin, 0);
  220.     }
  221.     Ausgabe(&bin, 0);
  222.   }
  223.   else
  224.   {
  225.     Eingabe(&bin);
  226.     if(args.cdata)
  227.       Write(hex.file, "ULONG data[] = {\n", 17);
  228.     while(bin.count && !CTRL_C)
  229.     {
  230.       if(args.asmdata)
  231.       {
  232.         *(hex.pos++) = '\t';
  233.         *(hex.pos++) = 'D';
  234.         *(hex.pos++) = 'C';
  235.         *(hex.pos++) = '.';
  236.         *(hex.pos++) = 'L';
  237.         *(hex.pos++) = '\t';
  238.       }
  239.       else if(args.cdata)
  240.       {
  241.     *(hex.pos++) = ' ';
  242.     *(hex.pos++) = ' ';
  243.       }
  244.       strptr = hex.pos + ASCIIPOS;
  245.  
  246.       for(h = 0; h < NUMPERLINE; ++h, ++bin.pos)
  247.       {
  248.         if(bin.pos < bin.buf + bin.count)
  249.         {
  250.       if((args.asmdata || args.cdata) && !(h&3))
  251.           {
  252.             if(h)
  253.               *(hex.pos++) = ',';
  254.         if(args.asmdata)
  255.           *(hex.pos++) = '$';
  256.         else
  257.         {
  258.           *(hex.pos++) = '0';
  259.           *(hex.pos++) = 'x';
  260.         }
  261.           }
  262.       MakeHEX(hex.pos, 2, *bin.pos);
  263.       hex.pos += 2;
  264.           if(!args.onlydata)
  265.             *(strptr++) = SDI_isprint(*bin.pos) ? *bin.pos : '.';
  266.         }
  267.     else if(args.onlydata)
  268.       break;
  269.         else
  270.         {
  271.           *(hex.pos++) = ' '; *(hex.pos++) = ' ';
  272.           *(strptr++) = ' ';
  273.         }
  274.         if(!((h+1 & 3) || args.onlydata))
  275.           *(hex.pos++) = ' ';
  276.       }
  277.       if(!args.onlydata)
  278.       {
  279.         MakeHEX(hex.pos, 8, adress);
  280.         *(hex.pos-1) = '\t'; *(hex.pos+8) = ' ';  *strptr = '\n';
  281.         hex.pos += RESTSIZE;
  282.       }
  283.       else
  284.       {
  285.     if(args.cdata)
  286.       *(hex.pos++) = ',';
  287.     *(hex.pos++) = '\n';
  288.       }
  289.       adress += NUMPERLINE;
  290.       if(bin.pos >= bin.buf + bin.count - NUMPERLINE)
  291.         Eingabe(&bin);
  292.       if(hex.pos >= hex.buf + hex.size - LINESIZE)
  293.       {
  294. #ifdef DEBUG
  295.   if(hex.pos > hex.buf + hex.size)
  296.     PutStr("Buffer overworked\n");
  297. #endif
  298.         Ausgabe(&hex, 0);
  299.       }
  300.     }
  301.     if(args.cdata)
  302.     {
  303.       *(hex.pos++) = '}';
  304.       *(hex.pos++) = ';';
  305.       *(hex.pos++) = '\n';
  306.     }
  307.     Ausgabe(&hex, 0);
  308.   }
  309.  
  310.   End(RETURN_OK);
  311. }
  312.  
  313. UBYTE GetHEXNum(UBYTE h)
  314. {
  315.   if(h > 47 && h < 58)
  316.     return (h - '0');
  317.   else if(h > 64 && h < 71)
  318.     return (h - 'A' + 10);
  319.   else if(h > 96 && h < 103)
  320.     return (h - 'a' + 10);
  321.   return 0;
  322. }
  323.  
  324. void end(void)
  325. {
  326.   if(bin.file)        Close(bin.file);
  327.   if(hex.file)        Close(hex.file);
  328.   Free(&bin);
  329.   Free(&hex);
  330.   if(rda)
  331.   {
  332.     FreeArgs(rda);
  333.     FreeDosObject(DOS_RDARGS, rda);
  334.   }
  335. }
  336.